﻿namespace USElections.Vote.Pages
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Net;
    using System.Text;
    using System.Windows;
    using System.Windows.Media;
    using Microsoft.Phone.Controls;
    using Microsoft.Phone.Shell;
    using Microsoft.Phone.Tasks;
    using NorthernLights;
    using USElections.Model;
    using USElections.Model.JSON;
    using USElections.TileUpdates;

    /// <summary>
    /// VotePage class.
    /// </summary>
    public partial class VotePage : PhoneApplicationPage
    {
        #region region
        private static string theText = "yourtext";
        private static string thePassword = "yourpassword";
        #endregion

        #region Constructor
        /// <summary>
        /// Initializes a new instance of the VotePage class.
        /// </summary>
        public VotePage()
        {
            InitializeComponent();

            this.candidatesListPicker.ItemsSource = Data.Instance.RunningCandidates;

            Dictionary<string, string> states = new Dictionary<string, string>();
            states.Add("-- SELECT --", "-- SELECT --");

            foreach (var state in States.StatesWithFullNames)
            {
                states.Add(state.Key, state.Value);
            }

            this.statesListPicker.ItemsSource = states; // Model.JSON.States.StatesWithFullNames;

            int votedcandidate = PersistentVariables.Get<int>(Model.Enums.Variables.VotedCandidate.ToString());

            if (votedcandidate != default(int))
            {
                Candidate candidate = Data.Instance.Candidates.GetCandidateById(votedcandidate);

                if (candidate != null && candidate.Running)
                {
                    this.notification.Show("You already voted, are you sure you want to change your vote?", new SolidColorBrush(Colors.Orange), null);
                }
            }

            this.CheckShareButton();
        }
        #endregion

        #region Private methods
        private void ApplicationBarIconButtonClick(object sender, EventArgs e)
        {
            ApplicationBarIconButton item = sender as ApplicationBarIconButton;

            if (item != null)
            {
                if (string.Compare(item.Text, "vote", StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    // send vote.
                    this.SendVote();
                }

                if (string.Compare(item.Text, "share", StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    var candidate = GetVotedCandidate();

                    if (candidate != null)
                    {
                        // http://www.uselectionsapp.com url
                        string shortenedUrl = "http://bit.ly/xoFOJA";

                        ShareStatusTask sst = new ShareStatusTask();

                        string status = string.Format("I voted for {0} @{1} ! #US #Elections (@uselectionsapp for Windows Phone {2} #wp)", candidate.FullName, candidate.TwitterAccount, shortenedUrl);

                        sst.Status = status;

                        if (sst.Status.Length > 140)
                        {
                            Debug.WriteLine("WARNING: Status too long for twitter!");
                        }

                        try
                        {
                            sst.Show();
                        }
                        catch
                        {
                        }
                    }
                }
            }
        }

        private void SendVote()
        {
            var selectedState = ((KeyValuePair<string, string>)this.statesListPicker.SelectedItem).Key;

            if (selectedState.Contains("--") && !(bool)this.USCheckBox.IsChecked)
            {
                this.notification.Show(
                    "Select a state or check 'Not a US citizen'.",
                    new SolidColorBrush(Colors.Orange),
                    null);
                return;
            }

            SystemTray.ProgressIndicator.IsVisible = true;

            Candidate candidate = this.candidatesListPicker.SelectedItem as Candidate;
            int candidateId = candidate.Id;

            string state = "XX";

            if (!(bool)this.USCheckBox.IsChecked)
            {
                state = selectedState;
            }

            string anid = USElections.Utils.General.GetWindowsLiveAnonymousID();

            PersistentVariables.Set<int>(Model.Enums.Variables.VotedCandidate.ToString(), candidateId);
            PersistentVariables.Set<string>(Model.Enums.Variables.VotedState.ToString(), state);

            ApplicationTile.SetPhoto();

            this.SendVoteToHttpEndpoint(
                anid, 
                candidateId, 
                state, 
                () => 
                {
                    // successful.
                    this.notification.Dispatcher.BeginInvoke(() =>
                    {
                        SystemTray.ProgressIndicator.IsVisible = false;

                        this.notification.Show(
                            "Thanks for voting, click here to go to the results page",
                            new SolidColorBrush(Colors.Green),
                            () =>
                            {
                                NavigationService.Navigate(new Uri("/USElections.Map;component/Pages/MapPage.xaml", UriKind.Relative));
                            });
                    });

                    this.CheckShareButton();
                }, 
                () => 
                {
                    // failed.
                    this.notification.Dispatcher.BeginInvoke(() =>
                    {
                        SystemTray.ProgressIndicator.IsVisible = false;

                        this.notification.Show(
                            "Sorry, something went wrong. Try again later.", 
                            new SolidColorBrush(Colors.Red),
                            null);
                    });
                });
        }

        private void SendVoteToHttpEndpoint(string anid, int candidate, string state, Action successful, Action failed)
        {
            string encryption = Utils.General.EncryptA(theText, thePassword, anid.ToString());

            string uri = string.Format("http://www.uselectionsapp.com/data/vote.php?anid={0}&candidate={1}&state={2}&encryption={3}", anid, candidate, state, HttpUtility.UrlEncode(encryption));

            try
            {
                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
                webRequest.Method = "POST";
                webRequest.ContentType = "application/x-www-form-urlencoded";

                webRequest.BeginGetRequestStream(
                    r =>
                    {
                        try
                        {
                            HttpWebRequest request1 = (HttpWebRequest)r.AsyncState;
                            Stream postStream = request1.EndGetRequestStream(r);

                            string postData = string.Empty;
                            byte[] byteArray = Encoding.UTF8.GetBytes(postData);

                            postStream.Write(byteArray, 0, byteArray.Length);
                            postStream.Close();

                            request1.BeginGetResponse(
                                s =>
                                {
                                    try
                                    {
                                        HttpWebRequest request2 = (HttpWebRequest)s.AsyncState;
                                        HttpWebResponse response = (HttpWebResponse)request2.EndGetResponse(s);

                                        Stream streamResponse = response.GetResponseStream();
                                        StreamReader streamReader = new StreamReader(streamResponse);
                                        string response2 = streamReader.ReadToEnd();
                                        streamResponse.Close();
                                        streamReader.Close();
                                        response.Close();

                                        if (successful != null)
                                        {
                                            successful();
                                            return;
                                        }
                                    }
                                    catch
                                    {
                                        if (failed != null)
                                        {
                                            failed();
                                            return;
                                        }
                                    }
                                },
                            request1);
                        }
                        catch
                        {
                            if (failed != null)
                            {
                                failed();
                                return;
                            }
                        }
                    },
                webRequest);
            }
            catch
            {
            }
        }

        private static Candidate GetVotedCandidate()
        {
            int votedcandidate = PersistentVariables.Get<int>(Model.Enums.Variables.VotedCandidate.ToString());

            if (votedcandidate != default(int))
            {
                return Data.Instance.Candidates.GetCandidateById(votedcandidate);
            }

            return null;
        }

        private void CheckShareButton()
        {
            if (GetVotedCandidate() != null)
            {
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    var button = ApplicationBar.Buttons[1] as ApplicationBarIconButton;
                    button.IsEnabled = true;
                });
            }
        }
        #endregion
    }
}